package dao;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;

import database.DatabaseManager;

import bean.BidBean;

/**
 * Data Access Object with static functions concerning actions on the table
 * AuctionBids within the Database
 * 
 * @author Sander Meijer & Stijn Kliemesch
 * 
 */
public class BidDAO {

	/**
	 * Gets all bids for a certain auctionID;
	 * 
	 * @param auctionItemID int
	 * @return ArrayList {@link BidBean}
	 */
	public static ArrayList<BidBean> getBidsForAuctionID(int auctionItemID) {

		ArrayList<BidBean> retList = new ArrayList<BidBean>();

		PreparedStatement psGetBidForAuctionID;
		ResultSet rsGetBidForAuctionID;

		String getBidForAuctionIDQuery = 
			"SELECT * FROM AuctionBids "+ 
			"WHERE AuctionID = ? " + 
			"ORDER BY BidValue DESC";

		try {
			psGetBidForAuctionID = 
				DatabaseManager.getInstance().getConnection().prepareStatement(getBidForAuctionIDQuery);
			psGetBidForAuctionID.setInt(1, auctionItemID);
			rsGetBidForAuctionID = psGetBidForAuctionID.executeQuery();

			while (rsGetBidForAuctionID.next()) {
				retList.add(createBidBean(rsGetBidForAuctionID));
			}

			psGetBidForAuctionID.close();
			rsGetBidForAuctionID.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return retList;
	}

	/**
	 * Gets all bids for a certain UserID
	 * 
	 * @param userID int
	 * @return ArrayList {@link BidBean}
	 */
	public static ArrayList<BidBean> getBidsForUserID(int userID) {
		
		ArrayList<BidBean> retList = new ArrayList<BidBean>();

		PreparedStatement psGetBidForUserID;
		ResultSet rsGetBidForUserID;

		String getGetBidForuserIDQuery = 
			"SELECT * FROM AuctionBids WHERE UserID = ?";

		try {
			psGetBidForUserID = 
				DatabaseManager.getInstance().getConnection()
					.prepareStatement(getGetBidForuserIDQuery);
			psGetBidForUserID.setInt(1, userID);
			rsGetBidForUserID = psGetBidForUserID.executeQuery();

			while (rsGetBidForUserID.next()) {	
				retList.add(createBidBean(rsGetBidForUserID));
			}

			psGetBidForUserID.close();
			rsGetBidForUserID.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return retList;
	}

	/**
	 * Gets the highest bid for the given paramter
	 * 
	 * @param auctionItemID int
	 * @return {@link BidBean}
	 */
	public static BidBean getTopBidForAuction(int auctionItemID) {
		
		BidBean retBean = new BidBean();

		PreparedStatement psGetTopBidForAuction;
		ResultSet rsGetTopBidForAuction;

		String getTopBidForAuctionQuery = 
			"SELECT * FROM AuctionBids " +
			"WHERE AuctionID = ? " +
			"ORDER BY BidValue DESC";

		try {
			psGetTopBidForAuction = 
				DatabaseManager.getInstance().getConnection()
				.prepareStatement(getTopBidForAuctionQuery);
			psGetTopBidForAuction.setInt(1, auctionItemID);
			psGetTopBidForAuction.setMaxRows(1);
			rsGetTopBidForAuction = psGetTopBidForAuction.executeQuery();

			while (rsGetTopBidForAuction.next()) {
				retBean = createBidBean(rsGetTopBidForAuction);
			}

			psGetTopBidForAuction.close();
			rsGetTopBidForAuction.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return retBean;
	}

	/**
	 * Inserts a bid with the current time value and the given paramters
	 * 
	 * @param auctionID int
	 * @param userID int
	 * @param bidValue int
	 */
	public static void insertBid(int auctionID, int userID, int bidValue) {

		PreparedStatement psInsertBid;
		String insertBidQuery = 
			"INSERT INTO AuctionBids (BidValue, Time, AuctionID, UserID) " +
			"VALUES (?, ?, ?, ?)";
		Date currentTime = new Date(Calendar.getInstance().getTimeInMillis());

		try {
			psInsertBid = 
				DatabaseManager.getInstance().getConnection()
					.prepareStatement(insertBidQuery);

			psInsertBid.setInt(1, bidValue);
			psInsertBid.setDate(2, currentTime);
			psInsertBid.setInt(3, auctionID);
			psInsertBid.setInt(4, userID);

			psInsertBid.execute();
			psInsertBid.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Deletes all bids from AuctionBids with the given parameter.
	 * 
	 * @param auctionID int
	 */
	public static void deleteBidByAuctionID(int auctionID) {

		PreparedStatement psDeleteBidsByAuctionID;
		String deleteBidsByAuctionID = 
			"DELETE FROM AuctionBids WHERE AuctionID=?";

		try {
			psDeleteBidsByAuctionID = 
				DatabaseManager.getInstance().getConnection()
					.prepareStatement(deleteBidsByAuctionID);
			psDeleteBidsByAuctionID.setInt(1, auctionID);


			psDeleteBidsByAuctionID.execute();
			psDeleteBidsByAuctionID.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Deletes all bids from AuctionBids with the given parameter.
	 * 
	 * @param userID int
	 */
	public static void deleteBidsByUserID(int userID) {

		PreparedStatement psDeleteBidsByUserID;
		String deleteBidsByUserID = 
			"DELETE FROM AuctionBids WHERE UserID=?";

		try {
			psDeleteBidsByUserID = 
				DatabaseManager.getInstance().getConnection()
					.prepareStatement(deleteBidsByUserID);
			psDeleteBidsByUserID.setInt(1, userID);

			psDeleteBidsByUserID.execute();
			psDeleteBidsByUserID.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Constructs a bidBean from a given resultSet
	 * @param rs resultSet
	 * @return {@link BidBean}
	 * @throws SQLException
	 */
	private static BidBean createBidBean(ResultSet rs) throws SQLException{
		
		BidBean retBean;
		
		int userID = rs.getInt("UserID");
		int auctionItemID = rs.getInt("AuctionID");
		int value = rs.getInt("BidValue");
		Date bidTime = rs.getDate("Time");

		String userName = UserDAO.getUserByID(userID).getUserName();

		retBean =new BidBean(auctionItemID, userID, userName, value,
				bidTime);
		
		return retBean;
	}
}
